﻿#include <Windows.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
#pragma comment(linker, "/EXPORT:GetFileVersionInfoA=_AheadLib_GetFileVersionInfoA,@1")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoByHandle=_AheadLib_GetFileVersionInfoByHandle,@2")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoExA=_AheadLib_GetFileVersionInfoExA,@3")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoExW=_AheadLib_GetFileVersionInfoExW,@4")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeA=_AheadLib_GetFileVersionInfoSizeA,@5")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeExA=_AheadLib_GetFileVersionInfoSizeExA,@6")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeExW=_AheadLib_GetFileVersionInfoSizeExW,@7")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeW=_AheadLib_GetFileVersionInfoSizeW,@8")
#pragma comment(linker, "/EXPORT:GetFileVersionInfoW=_AheadLib_GetFileVersionInfoW,@9")
#pragma comment(linker, "/EXPORT:VerFindFileA=_AheadLib_VerFindFileA,@10")
#pragma comment(linker, "/EXPORT:VerFindFileW=_AheadLib_VerFindFileW,@11")
#pragma comment(linker, "/EXPORT:VerInstallFileA=_AheadLib_VerInstallFileA,@12")
#pragma comment(linker, "/EXPORT:VerInstallFileW=_AheadLib_VerInstallFileW,@13")
#pragma comment(linker, "/EXPORT:VerLanguageNameA=_AheadLib_VerLanguageNameA,@14")
#pragma comment(linker, "/EXPORT:VerLanguageNameW=_AheadLib_VerLanguageNameW,@15")
#pragma comment(linker, "/EXPORT:VerQueryValueA=_AheadLib_VerQueryValueA,@16")
#pragma comment(linker, "/EXPORT:VerQueryValueW=_AheadLib_VerQueryValueW,@17")
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 原函数地址指针
PVOID pfnGetFileVersionInfoA;
PVOID pfnGetFileVersionInfoByHandle;
PVOID pfnGetFileVersionInfoExA;
PVOID pfnGetFileVersionInfoExW;
PVOID pfnGetFileVersionInfoSizeA;
PVOID pfnGetFileVersionInfoSizeExA;
PVOID pfnGetFileVersionInfoSizeExW;
PVOID pfnGetFileVersionInfoSizeW;
PVOID pfnGetFileVersionInfoW;
PVOID pfnVerFindFileA;
PVOID pfnVerFindFileW;
PVOID pfnVerInstallFileA;
PVOID pfnVerInstallFileW;
PVOID pfnVerLanguageNameA;
PVOID pfnVerLanguageNameW;
PVOID pfnVerQueryValueA;
PVOID pfnVerQueryValueW;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 宏定义
#define EXTERNC extern "C"
#define NAKED __declspec(naked)
#define EXPORT __declspec(dllexport)

#define ALCPP EXPORT NAKED
#define ALSTD EXTERNC EXPORT NAKED void __stdcall
#define ALCFAST EXTERNC EXPORT NAKED void __fastcall
#define ALCDECL EXTERNC NAKED void __cdecl
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AheadLib 命名空间
namespace AheadLib
{
	HMODULE m_hModule = NULL;		// 原始模块句柄
	HMODULE m_hMyModule = NULL;		// 原始模块句柄
	DWORD m_dwReturn[17] = { 0 };	// 原始函数返回地址


	// 获取原始函数地址
	FARPROC WINAPI GetAddress(PCSTR pszProcName)
	{
		FARPROC fpAddress;
		CHAR szProcName[16];
		TCHAR tzTemp[MAX_PATH];

		fpAddress = GetProcAddress(m_hModule, pszProcName);
		if (fpAddress == NULL)
		{
			if (HIWORD(pszProcName) == 0)
			{
				wsprintfA(szProcName, "%d", pszProcName);
				pszProcName = szProcName;
			}

			wsprintf(tzTemp, TEXT("无法找到函数 %hs，程序无法正常运行。"), pszProcName);
			MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
			ExitProcess(-2);
		}

		return fpAddress;
	}

	// 检测游戏当前窗口的界面   也就是检测游戏是否进入来判断是否打开辅助界面和相关初始化
	void CheckWinFm()
	{
		// 循环判断当前游戏窗口的界面状态
		HWND hWnd = NULL;
		do{
			hWnd = FindWindowA("", NULL);
		} while (!hWnd);

		DWORD WinSate = 0;
		do{
			// 自己在游戏找到当前窗口界面标识的地址
			WinSate = *(DWORD*)0X12345678;
		} while (!WinSate);

		// 载入辅助脚本的窗口或者相关初始化
		// ImGui初始化

		//载入DLL的方法
		m_hMyModule = LoadLibraryA("dxxy.dll");

	}

	// 初始化原始函数地址指针
	inline VOID WINAPI InitializeAddresses()
	{
		pfnGetFileVersionInfoA = GetAddress("GetFileVersionInfoA");
		pfnGetFileVersionInfoByHandle = GetAddress("GetFileVersionInfoByHandle");
		pfnGetFileVersionInfoExA = GetAddress("GetFileVersionInfoExA");
		pfnGetFileVersionInfoExW = GetAddress("GetFileVersionInfoExW");
		pfnGetFileVersionInfoSizeA = GetAddress("GetFileVersionInfoSizeA");
		pfnGetFileVersionInfoSizeExA = GetAddress("GetFileVersionInfoSizeExA");
		pfnGetFileVersionInfoSizeExW = GetAddress("GetFileVersionInfoSizeExW");
		pfnGetFileVersionInfoSizeW = GetAddress("GetFileVersionInfoSizeW");
		pfnGetFileVersionInfoW = GetAddress("GetFileVersionInfoW");
		pfnVerFindFileA = GetAddress("VerFindFileA");
		pfnVerFindFileW = GetAddress("VerFindFileW");
		pfnVerInstallFileA = GetAddress("VerInstallFileA");
		pfnVerInstallFileW = GetAddress("VerInstallFileW");
		pfnVerLanguageNameA = GetAddress("VerLanguageNameA");
		pfnVerLanguageNameW = GetAddress("VerLanguageNameW");
		pfnVerQueryValueA = GetAddress("VerQueryValueA");
		pfnVerQueryValueW = GetAddress("VerQueryValueW");
	}

	// 加载原始模块
	inline BOOL WINAPI Load()
	{
		TCHAR tzPath[MAX_PATH];
		TCHAR tzTemp[MAX_PATH * 2];
		// x86目录  C:\Windows\SysWOW64    x64目录  C:\Windows\System32	
		lstrcpy(tzPath, TEXT("C:\\Windows\\SysWOW64\\version.dll"));
		
		// 运行载入我们自己辅助脚本的线程
		::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CheckWinFm, NULL, NULL, NULL);

		m_hModule = LoadLibrary(tzPath);
		if (m_hModule == NULL)
		{
			wsprintf(tzTemp, TEXT("无法加载 %s，程序无法正常运行。"), tzPath);
			MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
		}
		else
		{
			InitializeAddresses();
		}

		return (m_hModule != NULL);
	}

	// 释放原始模块
	inline VOID WINAPI Free()
	{
		if (m_hModule)
		{
			FreeLibrary(m_hMyModule);
			FreeLibrary(m_hModule);
		}
	}
}
using namespace AheadLib;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 入口函数
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		DisableThreadLibraryCalls(hModule);

		return Load();
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
		Free();
	}

	return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_GetFileVersionInfoA(void)
{
	__asm JMP pfnGetFileVersionInfoA;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_GetFileVersionInfoByHandle(void)
{
	__asm JMP pfnGetFileVersionInfoByHandle;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_GetFileVersionInfoExA(void)
{
	__asm JMP pfnGetFileVersionInfoExA;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_GetFileVersionInfoExW(void)
{
	__asm JMP pfnGetFileVersionInfoExW;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_GetFileVersionInfoSizeA(void)
{
	__asm JMP pfnGetFileVersionInfoSizeA;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_GetFileVersionInfoSizeExA(void)
{
	__asm JMP pfnGetFileVersionInfoSizeExA;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_GetFileVersionInfoSizeExW(void)
{
	__asm JMP pfnGetFileVersionInfoSizeExW;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_GetFileVersionInfoSizeW(void)
{
	__asm JMP pfnGetFileVersionInfoSizeW;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_GetFileVersionInfoW(void)
{
	__asm JMP pfnGetFileVersionInfoW;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_VerFindFileA(void)
{
	__asm JMP pfnVerFindFileA;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_VerFindFileW(void)
{
	__asm JMP pfnVerFindFileW;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_VerInstallFileA(void)
{
	__asm JMP pfnVerInstallFileA;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_VerInstallFileW(void)
{
	__asm JMP pfnVerInstallFileW;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_VerLanguageNameA(void)
{
	__asm JMP pfnVerLanguageNameA;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_VerLanguageNameW(void)
{
	__asm JMP pfnVerLanguageNameW;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_VerQueryValueA(void)
{
	__asm JMP pfnVerQueryValueA;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_VerQueryValueW(void)
{
	__asm JMP pfnVerQueryValueW;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


